package ru.zombator.taskman.dbadmin.dialogs;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import ru.zombator.taskman.core.dbclient.IDbClient.Role;
import ru.zombator.taskman.core.domain.IManager;
import ru.zombator.taskman.core.domain.IPerson;
import ru.zombator.taskman.dbadmin.AdminApp;
import ru.zombator.taskman.dbadmin.ImageNames;

/**
 * Диалог "добавить/редактировать пользователя"
 * 
 * @author nvamelichev
 *
 */
public class AddEditUserDialog extends TitleAreaDialog {
	/**
	 * режим показа диалога
	 */
	public enum Mode {
		ADDING,
		EDITING
	}
	
	private Mode mode;
	private AdminApp mainApp;
	
	// визуальные компоненты //////////////////////////////////////////////////
	private String userName;
	private Text userNameText;
	
	private Role role;
	private Combo roleCombo;
	private static final int INDEX_WORKER = 0;
	private static final int INDEX_MANAGER = 1;
	
	private String ipAddress;
	private Text ipAddressText;
	///////////////////////////////////////////////////////////////////////////
	
	private static final int ALL_CLEAR = 0;
	private static final int INVALID_NAME = 1;
	private static final int INVALID_IP_ADDRESS = 2;
	private int validationStatus = ALL_CLEAR;
	
	/**
	 * @return введенное имя пользователя
	 */
	public String getUserName() {
		return userName;
	}
	
	/**
	 * @return введенная роль (менеджер или исполнитель)
	 */
	public Role getRole() {
		return role;
	}
	
	/**
	 * @return введенный IP-адрес
	 */
	public String getIpAddress() {
		return ipAddress;
	}
	
	/**
	 * слушатель, проверяющий на корректность введенные в поля значения
	 */
	private final ModifyListener VALIDATING_LISTENER =
		new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				checkValid();
				recordValues();
			}
		};
	
	public AddEditUserDialog(AdminApp mainApp, Mode mode) {
		super(mainApp.getShell());
		
		this.mainApp = mainApp;
		this.mode = mode;
	}

	private void recordValues() {
		if (roleCombo != null)
			role = (roleCombo.getSelectionIndex() == INDEX_WORKER ? Role.WORKER : Role.MANAGER);
		if (userNameText != null)
			userName = userNameText.getText();
		if (ipAddressText != null)
			ipAddress = ipAddressText.getText();
	}
	
	private void checkValid() {
		boolean isDataValid = isValid();
		Button okButton = getButton(IDialogConstants.OK_ID);
		if (okButton != null) {
			okButton.setEnabled(isDataValid);
		}
	}
	
	private boolean isValid() {
		if (userNameText.getText().length() == 0) {
			if (validationStatus != INVALID_NAME)
				setMessage("Введите имя пользователя", IMessageProvider.ERROR);
			validationStatus = INVALID_NAME;
			return false;
		}
		
		final String IP_ADDRESS_REGEX = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
		if (!ipAddressText.getText().matches(IP_ADDRESS_REGEX)) {
			if (validationStatus != INVALID_IP_ADDRESS)
				setMessage("Введите корректный IP-адрес", IMessageProvider.ERROR);
			validationStatus = INVALID_IP_ADDRESS;
			return false;
		}
		
		validationStatus = ALL_CLEAR;
		setMessage(null);
		return true;
	}
	
	@Override
	protected Control createDialogArea(Composite parent) {
		setTitle(mode.equals(Mode.ADDING) ? "Добавление пользователя":
			"Изменение пользователя");
		getShell().setText(mode.equals(Mode.ADDING) ? "Добавление пользователя":
			"Изменение пользователя");
		setTitleImage(mainApp.getRegistry().get(ImageNames.WIZ_LOGO));
		
		Composite dialogArea = new Composite(parent, SWT.NONE);
		dialogArea.setLayout(new GridLayout(1, false));
		dialogArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		
		Composite innerTable = new Composite(dialogArea, SWT.NONE);
		innerTable.setLayout(new GridLayout(2, false));
		innerTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		// имя пользователя: ...
		Label userName = new Label(innerTable, SWT.NONE);
		userName.setText("Имя пользователя:");
		userNameText = new Text(innerTable, SWT.BORDER);
		userNameText.setTextLimit(50);
		userNameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
		userNameText.addModifyListener(VALIDATING_LISTENER);
		
		// роль: ...
		Label role = new Label(innerTable, SWT.NONE);
		role.setText("Роль:");
		roleCombo = new Combo(innerTable, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
		roleCombo.add("исполнитель");
		roleCombo.add("менеджер");
		roleCombo.addModifyListener(VALIDATING_LISTENER);
		roleCombo.select(INDEX_WORKER);
		
		// IP-адрес: ...
		Label ipAddress = new Label(innerTable, SWT.NONE);
		ipAddress.setText("IP-адрес:");
		ipAddressText = new Text(innerTable, SWT.BORDER);
		ipAddressText.setTextLimit(15); // ex. 123.456.789.000
		ipAddressText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
		ipAddressText.addModifyListener(VALIDATING_LISTENER);

		// заполняем поля значениями из таблицы, если мы производим редактирование
		if (mode.equals(Mode.EDITING)) {
			IStructuredSelection sel = (IStructuredSelection) mainApp.getUsersTable().getSelection();
			Object first = sel.getFirstElement();
			IPerson firstPerson = (IPerson) first;
			userNameText.setText(firstPerson.getName());
			
			roleCombo.select(firstPerson instanceof IManager ? INDEX_MANAGER : INDEX_WORKER);
			roleCombo.setEnabled(false);
			
			ipAddressText.setText(firstPerson.getIpAddress());
		}
		
		return dialogArea;
	}
	
	@Override
	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		
		checkValid();
		return contents;
	}
	
	@Override
	protected Point getInitialSize() {
		return new Point(380, 265);
	}
}
